@use 'sass:map';
@use '@material/icon-button/icon-button' as mdc-icon-button;
@use '@material/icon-button/icon-button-theme' as mdc-icon-button-theme;
@use '@material/theme/custom-properties' as mdc-custom-properties;

@use '../core/tokens/m2/mdc/icon-button' as tokens-mdc-icon-button;
@use '../core/tokens/m2/mat/icon-button' as tokens-mat-icon-button;

@use './button-base';
@use '../core/style/private';
@use '../core/tokens/token-utils';

// The slots for tokens that will be configured in the theme can be emitted with no fallback.
@include mdc-custom-properties.configure($emit-fallback-values: false, $emit-fallback-vars: false) {
  $token-slots: tokens-mdc-icon-button.get-token-slots();

  // Add the MDC component static styles.
  @include mdc-icon-button.static-styles();

  .mat-mdc-icon-button {
    // Add the official slots for the MDC component.
    @include mdc-icon-button-theme.theme-styles(map.merge($token-slots, (
      // Exclude the state layer size since we'll re-emit it below with a default value.
      state-layer-size: null,
    )));
  }
}

.mat-mdc-icon-button {
  // Border radius is inherited by ripple to know its shape. Set to 50% so the ripple is round.
  border-radius: 50%;

  // Prevent the button from shrinking since it's always supposed to be a circle.
  flex-shrink: 0;

  // Ensure the icons are centered.
  text-align: center;

  svg {
    vertical-align: baseline;
  }

  @include token-utils.use-tokens(
    tokens-mdc-icon-button.$prefix, tokens-mdc-icon-button.get-token-slots()) {
    $button-size: var(#{token-utils.get-token-variable(state-layer-size)}, 48px);
    $icon-size: var(#{token-utils.get-token-variable(icon-size)}, 24px);

    // We emit these tokens ourselves here so we can provide a default value.
    // This avoids a lot internal breakages in apps that didn't include the icon button theme.
    width: $button-size;
    height: $button-size;

    // Note: this is wrapped in an interpolation, because of an internal lint rule that bans
    // interpolations in `calc`, even though this is the only way to achieve what we're looking for.
    padding: #{calc(#{calc(#{$button-size} - #{$icon-size})} / 2)};

    // Icon size used to be placed on the host element. Now, in `theme-styles` it is placed on
    // the unused `.mdc-button__icon` class. Explicitly set the font-size here.
    @include token-utils.create-token-slot(font-size, icon-size);

    @include button-base.mat-private-button-disabled {
      // MDC's disabled styles target the `:disabled` selector which doesn't work on links.
      // We re-apply the disabled icon color here since we support Material buttons on links too.
      @include token-utils.create-token-slot(color, disabled-icon-color);
    };
  }

  @include button-base.mat-private-button-interactive();
  @include button-base.mat-private-button-ripple(tokens-mat-icon-button.$prefix,
    tokens-mat-icon-button.get-token-slots());
  @include button-base.mat-private-button-touch-target(true, tokens-mat-icon-button.$prefix,
    tokens-mat-icon-button.get-token-slots());
  @include private.private-animation-noop();

  .mat-mdc-button-persistent-ripple {
    border-radius: 50%;
  }

  // MDC adds some styles to icon buttons that conflict with some of our focus indicator styles
  // and don't actually do anything. This undoes those conflicting styles.
  &.mat-unthemed,
  &.mat-primary,
  &.mat-accent,
  &.mat-warn {
    &:not(.mdc-ripple-upgraded):focus::before {
      background: transparent;
      opacity: 1;
    }
  }
}
